﻿#include <QEventLoop>
#include "CSensorSeriesCtrMange.h"
#include "CGlobal.h"
#include "Public.h"
#include "CAlarmPoint.h"
#include "CLogOper.h"

CSensorSeriesCtrMange::CSensorSeriesCtrMange(CDevDataSensorSeries* pDevData)
{
	m_pDevData = pDevData;
	m_pCtrOper = new CSensorSeriesOper(pDevData);
	m_pMutex = new QMutex(QMutex::Recursive);
	m_bhread.store(false);
	m_bShouldStop = false;
	m_bFrist = true;
	m_nGetStateCount = 0;
	m_nGetHistoryDataCount = 0;
	nChannel1ErrNum = 0;
	nChannel2ErrNum = 0;
	nChannel3ErrNum = 0;
	nChannel4ErrNum = 0;
	nChannel5ErrNum = 0;
	nChannel6ErrNum = 0;
	nChannel7ErrNum = 0;
	nChannel8ErrNum = 0;
}

CSensorSeriesCtrMange::~CSensorSeriesCtrMange()
{
	ThreadStop();
	m_bShouldStop = true;
	quit();
	wait();
	if (m_pCtrOper)
	{
		delete m_pCtrOper;
		m_pCtrOper = nullptr;
	}
	if (m_pMutex != nullptr)
	{
		delete m_pMutex;
		m_pMutex = nullptr;
	}
}

void CSensorSeriesCtrMange::ThreadStart()
{
	QMutexLocker locker(m_pMutex);
	if (!m_bhread.load())
	{
		if (m_bFrist)
		{
			start();
			m_bFrist = false;
		}
		m_bhread.store(true);
	}
}

void CSensorSeriesCtrMange::ThreadStop()
{
	QMutexLocker locker(m_pMutex);
	if (m_bhread.load())
	{
		m_bhread.store(false);
	}
}

/********************************************************************************
*Description: 设备控制执行函数
异步 添加到队列就返回成功
同步 执行成功就返回执行
*FunParameter: 设备控制结构体
*FunReturnValue: 成功或者失败
*Author:hjx
*Date:20250106
*ChangeDate:
*Modifier:
*ModifyReason:
*Version:V1.0.0
********************************************************************************/
bool CSensorSeriesCtrMange::CtrDevice(SCtrInfo& stCtrInfo)
{
	if (stCtrInfo.m_bCtrSync == true)
	{
		return m_pCtrOper->CtrDevice(stCtrInfo);
	}
	else
	{
		//如果线程没启动 开启线程
		if (!m_bhread)
			ThreadStart();
		if (m_pMutex->tryLock(3000))
		{
			if (m_vecCtrQueue.size() > 5)
				m_vecCtrQueue.clear();
			//如果是重复命令不添加
			if (m_vecCtrQueue.size() >= 1)
			{
				SCtrInfo stCtrInfoLast = m_vecCtrQueue[m_vecCtrQueue.size() - 1];
				if (stCtrInfo.m_nCtrCmd != stCtrInfoLast.m_nCtrCmd)
				{
					m_vecCtrQueue.push_back(stCtrInfo);
				}
			}
			else
			{
				m_vecCtrQueue.push_back(stCtrInfo);
			}
			m_pMutex->unlock();
			return true;
		}
		else
		{
			return false;
		}
	}
}

/********************************************************************************
*Description: 设备控制执行函数 设备本身调用
*FunParameter:
*FunReturnValue:
*Author:Gaojia
*Date:2024/02/06
*ChangeDate:
*Modifier:
*ModifyReason:
*Version:V1.0.0
********************************************************************************/
bool CSensorSeriesCtrMange::CtrDeviceEx(SCtrInfo& stCtrInfo)
{
	return CtrDevice(stCtrInfo);
}

void CSensorSeriesCtrMange::run()
{
	while (!m_bShouldStop)
	{
		QMutexLocker locker(m_pMutex);
		if (!m_bhread.load())
		{
			sysSleep(10);
			continue;
		}
		if (m_nGetStateCount >= 5)
		{
			m_pCtrOper->GetDevState();//读取设备状态
			m_nGetStateCount = 0;
		}
		else
		{
			m_nGetStateCount++;
		}

		if (m_nGetHistoryDataCount >= 900)
		{
			//生成日志
			SExecLog sDevExecLog;
			sDevExecLog.m_sDevName = m_pDevData->m_sDevName;
			sDevExecLog.m_sFuncName = A2T("历史数据");
			sDevExecLog.m_sDescriptionl = A2T("开始获取历史数据");
			sDevExecLog.m_nAlarmLevel = enWorkInfo;
			CLogOper::instance().addMsg(sDevExecLog);
			QDateTime currentDateTime = QDateTime::currentDateTime();
			QString sCurrentDateTime = currentDateTime.toString("yyyy-MM-ddTHH:mm:ssZ");
			// 获取一周前的时间
			QDateTime oneWeekAgo = currentDateTime.addDays(-1);
			QString sOneWeekAgo = oneWeekAgo.toString("yyyy-MM-ddTHH:mm:ssZ");
			m_pCtrOper->GetHistoryData(sOneWeekAgo, sCurrentDateTime);
			m_nGetHistoryDataCount = 0;
			sDevExecLog.m_sDescriptionl = A2T("获取历史数据结束");
			CLogOper::instance().addMsg(sDevExecLog);
		}
		else
		{
			m_nGetHistoryDataCount++;
		}

		//写测点
		writePoint();

		if (m_vecCtrQueue.size() > 0)
		{
			SCtrInfo stCtrInfo = m_vecCtrQueue[0];
			m_vecCtrQueue.remove(0);
			m_pCtrOper->CtrDevice(stCtrInfo);
		}
		sysSleep(1000);
	}
}

void CSensorSeriesCtrMange::writePoint()
{
	m_pDevData->m_mapDevPoint[enConnectState]->setValue(m_pDevData->m_nStateValue);

	for (auto itor = m_pDevData->m_mapChannel.begin(); itor != m_pDevData->m_mapChannel.end(); itor++)
	{
		SChannel item = itor.value();
		if (item.nIsEnable == 0)
		{
			continue;
		}
		processChannelState(item);
		processSensorState(item, enChannel1Temp, item.bTempState, item.m_dTemp);
		processSensorState(item, enChannel1Vibration, item.bVibrationState, item.m_dVicration);
		processSensorState(item, enChannel1Voice, item.bVoiceState, item.m_dVoice);
	}
}

void CSensorSeriesCtrMange::processChannelState(const SChannel& item)
{
	int& errNum = getChannelErrNum(item.nChannelNo);
	int statePoint = getChannelStatePoint(item.nChannelNo);

	if (item.nStateValue == false)
	{
		if (errNum == 10)
		{
			m_pDevData->m_mapDevPoint[(EDevPointType)statePoint]->setValue(false);
			errNum = 0;
		}
		else
		{
			m_pDevData->m_mapDevPoint[(EDevPointType)statePoint]->setValue(true);
			errNum++;
		}
	}
	else
	{
		m_pDevData->m_mapDevPoint[(EDevPointType)statePoint]->setValue(true);
		errNum = 0;
	}
}

void CSensorSeriesCtrMange::processSensorState(const SChannel& item, int basePoint,
	bool sensorState, const QDateTime& sensorTime)
{
	int point = getSensorPoint(item.nChannelNo, basePoint);

	if (sensorState == false)
	{
		if (sensorTime.secsTo(QDateTime::currentDateTime()) < 300)
		{
			m_pDevData->m_mapDevPoint[(EDevPointType)point]->setValue(false);
		}
		else
		{
			m_pDevData->m_mapDevPoint[(EDevPointType)point]->setValue(true);
		}
	}
	else
	{
		m_pDevData->m_mapDevPoint[(EDevPointType)point]->setValue(true);
	}
}

int& CSensorSeriesCtrMange::getChannelErrNum(int channelNo)
{
	static std::map<int, int*> errNumMap = 
	{
		{1, &nChannel1ErrNum}, {2, &nChannel2ErrNum}, {3, &nChannel3ErrNum}, {4, &nChannel4ErrNum},
		{5, &nChannel5ErrNum}, {6, &nChannel6ErrNum}, {7, &nChannel7ErrNum}, {8, &nChannel8ErrNum}
	};

	auto it = errNumMap.find(channelNo);
	return (it != errNumMap.end()) ? *(it->second) : nChannel1ErrNum; // 返回默认值
}

int CSensorSeriesCtrMange::getChannelStatePoint(int channelNo)
{
	static std::map<int, int> statePointMap = 
	{
		{1, enChannel1State}, {2, enChannel2State}, {3, enChannel3State}, {4, enChannel4State},
		{5, enChannel5State}, {6, enChannel6State}, {7, enChannel7State}, {8, enChannel8State}
	};

	auto it = statePointMap.find(channelNo);
	return (it != statePointMap.end()) ? it->second : enChannel1State; // 返回默认值
}

int CSensorSeriesCtrMange::getSensorPoint(int channelNo, int basePoint)
{
	static std::map<int, std::map<int, int>> sensorPointMap = 
	{
		{enChannel1Temp, {{1, enChannel1Temp}, {2, enChannel2Temp}, {3, enChannel3Temp}, {4, enChannel4Temp},
						 {5, enChannel5Temp}, {6, enChannel6Temp}, {7, enChannel7Temp}, {8, enChannel8Temp}}},
		{enChannel1Vibration, {{1, enChannel1Vibration}, {2, enChannel2Vibration}, {3, enChannel3Vibration}, {4, enChannel4Vibration},
							  {5, enChannel5Vibration}, {6, enChannel6Vibration}, {7, enChannel7Vibration}, {8, enChannel8Vibration}}},
		{enChannel1Voice, {{1, enChannel1Voice}, {2, enChannel2Voice}, {3, enChannel3Voice}, {4, enChannel4Voice},
						  {5, enChannel5Voice}, {6, enChannel6Voice}, {7, enChannel7Voice}, {8, enChannel8Voice}}}
	};

	auto baseIt = sensorPointMap.find(basePoint);
	if (baseIt != sensorPointMap.end()) {
		auto channelIt = baseIt->second.find(channelNo);
		if (channelIt != baseIt->second.end()) {
			return channelIt->second;
		}
	}
	return basePoint; // 返回默认值
}
